<mat-card class="p-5">
    @for (call of llmCalls(); track call.id; let i = $index) {
        <div class="pb-6">
            <!-- Summary Header -->
            <div id="{{ call.id }}" class="pb-2 flex items-center">
                @if(call.error) {
                    <mat-icon color="warn" class="mr-1 icon-size-5">error_outline</mat-icon>
                }
                <span class="mb-3 pt-3 font-medium text-xl">{{ call.description }}</span>
                <a [href]="llmCallUrl(call)" style="font-size: x-small" target="_blank" mat-icon-button matTooltip="Open in Firestore">
                    <mat-icon>storage</mat-icon>
                </a>
                <button mat-icon-button (click)="openInPromptStudio(call)" matTooltip="Open in Prompt Studio" style="font-size: x-small">
                    <mat-icon>library_books</mat-icon>
                </button>
                <button mat-icon-button (click)="createChatFromLlmCall(call.id)" matTooltip="Create a chat from this LLM call" style="font-size: x-small">
                    <mat-icon>forum</mat-icon>
                </button>
            </div>

            <div class="mb-1 text-sm">
                <strong>LLM:</strong> {{ getLlmName(call.llmId) }} &nbsp;&nbsp; <strong>Request Time:</strong>
                {{ call.requestTime | date : 'medium' }}. &nbsp;&nbsp; <strong>Total Time:</strong>
                {{ ((call.totalTime ?? 0) / 1000).toFixed(1) }}s&nbsp;&nbsp; <strong>Tokens in/out:</strong>
                {{ call.inputTokens }}/{{ call.outputTokens }}&nbsp;&nbsp; <strong>Cost: </strong> ${{
                    call.cost?.toFixed(4)
                }} <strong>Tok/S:</strong> {{ (call.outputTokens > 0 && call.totalTime > 0 ? (call.outputTokens / (call.totalTime / 1000)) : 0).toFixed(1) }}
            </div>

            <!-- Main Expansion Panel for Messages -->
            <mat-expansion-panel class="mb-1" (opened)="fetchLlmCallDetails(call)">
                <mat-expansion-panel-header>
                    <mat-panel-title>
                        Messages ({{ call.messageSummaries.length }})
                    </mat-panel-title>
                </mat-expansion-panel-header>
                <ng-template matExpansionPanelContent>
                    @let detailState = expandedLlmCallData()[call.id];
                    @if (detailState?.status === 'loading') {
                        <div class="flex justify-center items-center p-4">
                            <mat-spinner diameter="50"></mat-spinner>
                        </div>
                    } @else if (detailState?.status === 'success' && detailState?.data) {
                        <!-- Full Message Details -->
                        @for (message of detailState.data.messages; track $index) {
                            <mat-expansion-panel class="mb-1">
                                <mat-expansion-panel-header>
                                    <mat-panel-title>
                                        <span class="w-20">{{ message.role | titlecase }}:</span>
                                        <span class="expansion-preview">
                                            {{ getPreviewContent(message.content) | slice : 0 : 150 }}
                                            @if (getPreviewContent(message.content).length > 150) {
                                                <span>...</span>
                                            }
                                        </span>
                                        <clipboard-button [cdkCopyToClipboard]="toContentText(message.content)" class=""></clipboard-button>
                                    </mat-panel-title>
                                </mat-expansion-panel-header>
                                
                                @if (isArrayContent(message.content)) {
                                    @for (part of getContentAsArray(message.content); track part.type + '-' + $index) {
                                        <ng-container [ngSwitch]="part.type">
                                            <div *ngSwitchCase="'reasoning'">
                                                <mat-expansion-panel class="mb-3">
                                                    <mat-expansion-panel-header>
                                                        <mat-panel-title>
                                                            Reasoning
                                                        </mat-panel-title>
                                                    </mat-expansion-panel-header>
                                                    {{ part.text }}
                                                </mat-expansion-panel>
                                            </div>
                                            <div *ngSwitchCase="'text'">
                                                @if (message.role === 'assistant') {
                                                    <markdown
                                                        mermaid
                                                        clipboard
                                                        [clipboardButtonComponent]="clipboardButton"
                                                        [data]="part.text"
                                                    ></markdown>
                                                } @else {
                                                    <div style="white-space: pre-wrap; word-wrap: break-word;" [innerHTML]="convertNewlinesToHtml(part.text)"></div>
                                                }
                                            </div>
                                            <div *ngSwitchCase="'image'">[Image Part: {{ part.mediaType || 'type unknown' }}]</div>
                                            <div *ngSwitchCase="'file'">[File Part: {{ part.mediaType || 'type unknown' }}]</div>
                                            <div *ngSwitchCase="'tool-call'">[Tool Call: {{part.toolName}} ID: {{part.toolCallId}}]</div>
                                            <div *ngSwitchCase="'tool-result'">[Tool Result for {{part.toolName}} ID: {{part.toolCallId}}] <div style="white-space: pre-wrap; word-wrap: break-word;" [innerHTML]="convertNewlinesToHtml(part.result)"></div></div>
                                            <ng-container *ngSwitchDefault>
                                               <div>[Unknown Part Type: {{ part.type || 'N/A' }}]</div>
                                            </ng-container>
                                        </ng-container>
                                    }
                                } @else {
                                    @if (message.role === 'assistant') {
                                        <markdown
                                            mermaid
                                            clipboard
                                            [clipboardButtonComponent]="clipboardButton"
                                            [data]="isStringContent(message.content) ? message.content : ''"
                                        ></markdown>
                                    } @else {
                                        <div style="white-space: pre-wrap; word-wrap: break-word;" [innerHTML]="convertNewlinesToHtml(isStringContent(message.content) ? message.content : '')"></div>
                                    }
                                }
                            </mat-expansion-panel>
                        }
                    } @else if (detailState?.status === 'error') {
                        <div class="p-4 text-red-600">
                            Error loading full details: {{ detailState.error?.message || 'Unknown error' }}
                            <button mat-button color="primary" (click)="fetchLlmCallDetails(call)">Retry</button>
                        </div>
                    } @else {
                        <!-- Initial view with summaries from LlmCallSummary before full details are loaded -->
                        @for (msgSummary of call.messageSummaries; track $index) {
                            <div class="p-2 border-b">
                                <strong>{{ msgSummary.role | titlecase }}:</strong> {{ msgSummary.textPreview | slice : 0 : 200 }}
                                @if (msgSummary.textPreview && msgSummary.textPreview.length > 200) {<span>...</span>}
                                @if (msgSummary.imageCount > 0) { <span class="text-xs text-gray-500 ml-2"> ({{msgSummary.imageCount}} images)</span> }
                                @if (msgSummary.fileCount > 0) { <span class="text-xs text-gray-500 ml-2"> ({{msgSummary.fileCount}} files)</span> }
                            </div>
                        }
                    }
                </ng-template>
            </mat-expansion-panel>
        </div>
    }
    @if (llmCalls()?.length === 0 && llmCallsStateForTemplate().status !== 'loading' && llmCallsStateForTemplate().status !== 'idle') {
        <div>
            <p style="padding-left: 10px">No LLM calls found for this agent.</p>
        </div>
    }
    @if (llmCallsStateForTemplate().status === 'loading' || llmCallsStateForTemplate().status === 'idle') {
        <div class="flex justify-center items-center p-4">
            <mat-spinner diameter="50"></mat-spinner>
        </div>
    }
</mat-card>
